/* Descriptor status values */
#define RING_STATUS_OK 0 /* Everything is gravy. */
#define RING_STATUS_BAD_PAGE 1 /* What they gave us was pure evil */
+#define RING_STATUS_DROPPED 2 /* Unrouteable packet */
#endif
* VIF_DROP -- Drop this packet
* others -- Send to specified VIF (reference held on return)
*/
-#define VIF_PHYS ((net_vif_t *)0)
-#define VIF_DROP ((net_vif_t *)1)
+#define VIF_PHYS ((net_vif_t *)0)
+#define VIF_DROP ((net_vif_t *)1)
+#define VIF_LOCAL(_vif) ((unsigned long)(_vif) > 1)
#endif /* __XENO_VIF_H__ */
if ( skb->dst_vif == NULL )
skb->dst_vif = net_get_target_vif(skb->data, skb->len, skb->src_vif);
- if ( (skb->dst_vif == VIF_PHYS) || (skb->dst_vif == VIF_DROP) )
- {
- netdev_rx_stat[this_cpu].dropped++;
- unmap_domain_mem(skb->head);
- kfree_skb(skb);
- local_irq_restore(flags);
- return NET_RX_DROP;
- }
+ if ( !VIF_LOCAL(skb->dst_vif) )
+ skb->dst_vif = find_vif_by_id(0);
deliver_packet(skb, skb->dst_vif);
put_vif(skb->dst_vif);
target = net_get_target_vif(g_data, tx.size, vif);
- if ( target == VIF_PHYS )
- {
- vif->tx_shadow_ring[j].id = tx.id;
- vif->tx_shadow_ring[j].size = tx.size;
- vif->tx_shadow_ring[j].header =
- kmem_cache_alloc(net_header_cachep, GFP_KERNEL);
- if ( vif->tx_shadow_ring[j].header == NULL )
- {
- make_tx_response(vif, tx.id, RING_STATUS_OK);
- goto tx_unmap_and_continue;
- }
-
- memcpy(vif->tx_shadow_ring[j].header, g_data, PKT_PROT_LEN);
- vif->tx_shadow_ring[j].payload = tx.addr + PKT_PROT_LEN;
- get_page_tot(buf_page);
- j = TX_RING_INC(j);
- }
- else if ( target != VIF_DROP )
+ if ( VIF_LOCAL(target) )
{
/* Local delivery */
if ( (skb = dev_alloc_skb(ETH_FRAME_LEN + 32)) == NULL )
make_tx_response(vif, tx.id, RING_STATUS_OK);
}
+ else if ( (target == VIF_PHYS) || IS_PRIV(current) )
+ {
+ vif->tx_shadow_ring[j].id = tx.id;
+ vif->tx_shadow_ring[j].size = tx.size;
+ vif->tx_shadow_ring[j].header =
+ kmem_cache_alloc(net_header_cachep, GFP_KERNEL);
+ if ( vif->tx_shadow_ring[j].header == NULL )
+ {
+ make_tx_response(vif, tx.id, RING_STATUS_OK);
+ goto tx_unmap_and_continue;
+ }
+
+ memcpy(vif->tx_shadow_ring[j].header, g_data, PKT_PROT_LEN);
+ vif->tx_shadow_ring[j].payload = tx.addr + PKT_PROT_LEN;
+ get_page_tot(buf_page);
+ j = TX_RING_INC(j);
+ }
+ else
+ {
+ make_tx_response(vif, tx.id, RING_STATUS_DROPPED);
+ }
tx_unmap_and_continue:
unmap_domain_mem(g_data);
struct net_private *np;
int idx = -1;
network_op_t op;
- static int removed_bootstrap_rules = 0;
list_for_each ( ent, &dev_list )
{
- np = list_entry(dev_list.next, struct net_private, list);
+ np = list_entry(dev_list.next, struct net_private, list);
if ( np->dev == dev )
idx = np->idx;
}
op.u.net_rule.dst_addr = ntohl(ifa->ifa_address);
op.u.net_rule.dst_addr_mask = ~0UL;
(void)HYPERVISOR_network_op(&op);
-
- /*
- * When the first real interface is brought up we delete the start-of-day
- * bootstrap rules -- they were only installed to allow an initial DHCP
- * request and response.
- */
- if ( (idx == 0) && (event == NETDEV_UP) && !removed_bootstrap_rules )
- {
- memset(&op, 0, sizeof(op));
- op.cmd = NETWORK_OP_DELETERULE;
- op.u.net_rule.proto = NETWORK_PROTO_ANY;
- op.u.net_rule.action = NETWORK_ACTION_ACCEPT;
- op.u.net_rule.src_vif = 0;
- op.u.net_rule.dst_vif = VIF_PHYSICAL_INTERFACE;
- (void)HYPERVISOR_network_op(&op);
- op.u.net_rule.src_vif = VIF_ANY_INTERFACE;
- op.u.net_rule.dst_vif = 0;
- (void)HYPERVISOR_network_op(&op);
-
- removed_bootstrap_rules = 1;
- }
out:
return NOTIFY_DONE;
INIT_LIST_HEAD(&dev_list);
+ /*
+ * Domain 0 must poke its own network rules as it discovers its IP
+ * addresses. All other domains have a privileged "parent" to do this for
+ * them at start of day.
+ */
if ( start_info.dom_id == 0 )
- {
- /*
- * Domain 0 creates wildcard rules to allow DHCP to find its first IP
- * address. These wildcard rules are deleted when the first inet
- * interface is brought up.
- */
- network_op_t op;
- memset(&op, 0, sizeof(op));
- op.cmd = NETWORK_OP_ADDRULE;
- op.u.net_rule.proto = NETWORK_PROTO_ANY;
- op.u.net_rule.action = NETWORK_ACTION_ACCEPT;
- op.u.net_rule.src_vif = 0;
- op.u.net_rule.dst_vif = VIF_PHYSICAL_INTERFACE;
- (void)HYPERVISOR_network_op(&op);
- op.u.net_rule.src_vif = VIF_ANY_INTERFACE;
- op.u.net_rule.dst_vif = 0;
- (void)HYPERVISOR_network_op(&op);
-
- /*
- * Domain 0 must poke its own network rules as it discovers its IP
- * addresses. All other domains have a privileged "parent" to do this
- * for them at start of day.
- */
(void)register_inetaddr_notifier(¬ifier_inetdev);
- }
for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
{